<template>
  <div class="permission-container">
    <div class="app-container">
      <!-- 表格 -->
      <el-card>
       <div class="card_header">
         <div>
           <h3>权限点列表</h3>
         </div>
         <div>
           <!-- 添加父级一级id -->
           <el-button type="primary" size="small" @click="addPerBtnFn(1,'0')">添加权限</el-button>
         </div>
       </div>
       <!-- 权限点 table -->
        <el-table border :data="allPermissionList" row-key="id" default-expand-all>
          <el-table-column label="名称" prop="name"/>
          <el-table-column label="标识" prop="code"/>
          <el-table-column label="描述" prop="description"/>
          <el-table-column label="操作">
            <template #default="{row}">
              <!-- 添加子级二级id -->
              <el-button v-if="row.type == 1" type="text" @click="addPerBtnFn(2,row.id)">添加</el-button>
              <el-button type="text" @click="updatePerBtnFn(row)">编辑</el-button>
              <el-button type="text" @click="del(row.id)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-card>
    </div>
    <!-- dialog -->
    <!-- 当mounted执行完毕,该组件也加载完毕了,只是隐藏了而已 -->
    <role-dialog ref="roledialog" @addpermission="addPermissionFn" :isEdit="isEdit"/>
  </div>
</template>
<script>
  import { getPermissionListAPI, addPermissionAPI, getPermissionDetailAPI,
  updatePermissionAPI, delPermissionAPI } from '@/api'
  import { transTree } from '@/utils/handleTreeData'
  import RoleDialog from './component/roleDialog.vue'
export default {
  name: 'PermissionIndex',
  data() {
    return {
      allPermissionList: [], //权限点列表(嵌套children数组)
      permissionList: [], // 权限点列表(扁平数组,后端返回的原始数组)
      isEdit: false, // 新增/编辑模式区分
    }
  },
  created(){
    this.getPermissionListFn()
  },
  mounted(){},
  methods: {
    // 获取所有权限节点数据
    async getPermissionListFn(){
      const res = await getPermissionListAPI()
      // 先保存一份扁平数据(原始数据),子组件自定义校验使用,这里通过ref直接劫持子组件
      this.permissionList = JSON.parse(JSON.stringify(res.data)).map(item => {
        if(item){
          item.name = item.name.trim()
        }
        return item
      })
      // transTree内部在查找的时候,参数2,要传递父级id(递归找子对象)
      // 目标: 为了让 pid 为 '0'的对象,在数组里第一层(父级,先找第一层)
      this.allPermissionList = transTree(res.data,"0")
    },
    // 点击当前 row 添加按钮时的事件 / 点击 header 添加按钮事件
    // type: 右上角按钮传下来1(父),当前 row 传下来是2(子级),(type值作为新对象的 type 使用)
    // pid: 右上角按钮传下来是 '0', 当前 row 传下来是 当前 row.id ,(pid也是给新对象pid使用)(当前row子级使用)
    addPerBtnFn(type,pid){ // 共用一个 dialog
      this.isEdit = false // 新增模式
      this.$refs.roledialog.showDialog = true // 展示 dialog
      this.$nextTick(() => { // 等待 dialog 组件渲染完毕才赋值
        this.$refs.roledialog.formData.type = type // 发送 params 对象
        this.$refs.roledialog.formData.pid = pid // 发送 params 对象
        this.$refs.roledialog.permissionList = this.permissionList
      })
    },
    // 自定义事件 -> 新增权限节点
    async addPermissionFn(formObj){
      if(this.isEdit){ // 编辑模式 , formObj为数据回显的对象并非新增时的对象,已经覆盖掉原来的formData新增表单对象了
          const res = await updatePermissionAPI(formObj)
          this.$message('修改权限节点成功')
      }else{ // 新增模式, formObj为最初定义的对象,没被回显数据的formData对象所覆盖
        try{
          const res = await addPermissionAPI(formObj)
          this.$message('新增权限节点成功')
        }catch(e){
          this.$message(e,'error')
        }
      }
      this.getPermissionListFn() // 刷新节点列表
    },
    // 编辑权限节点(共用一个 dialog)
    async updatePerBtnFn(row){
      this.isEdit = true // 编辑模式
      this.$refs.roledialog.showDialog = true // 展示 dialog
      const res = await getPermissionDetailAPI(row.id) // 接口返回的 message 有误,后台还没修改
      this.$nextTick(() => { // 等待 dialog 组件渲染完毕才赋值
        this.$refs.roledialog.formData = res.data // 查询该 row 数据成功,回显数据,覆盖原 formData 新增表单对象
        this.$refs.roledialog.permissionList = this.permissionList
      })
    },
    // 删除权限点
    async del(rowId){
      const res = await delPermissionAPI(rowId)
      this.$message('删除成功')
      this.getPermissionListFn()
    }
  },
  computed: {},
  components: {
    RoleDialog
  }
}
</script>
<style lang="scss" scope>
  .card_header {
      display: flex;
      justify-content: space-between;
      align-items: center;
  }
</style>
